package rullekake.entities;

import java.io.Serializable;
import java.util.Collection;
import javax.persistence.Basic;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.Lob;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.Table;

/**
 * Emneklasse.
 * Holder på alle data og relasjonsinformasjon for emner. Består av set/get for alt + equals, hashcode og toString.
 * 
 */

@Entity
@Table(name = "COURSE")
@NamedQueries({
    @NamedQuery(name = "Course.findAll", query = "SELECT c FROM Course c"),
    @NamedQuery(name = "Course.findByCourseId", query = "SELECT c FROM Course c WHERE c.courseId = :courseId"),
    @NamedQuery(name = "Course.findByCourseCode", query = "SELECT c FROM Course c WHERE c.courseCode = :courseCode"),
    @NamedQuery(name = "Course.findByCourseName", query = "SELECT c FROM Course c WHERE c.courseName = :courseName"),
    @NamedQuery(name = "Course.findByCourseNameNo", query = "SELECT c FROM Course c WHERE c.courseNameNo = :courseNameNo"),
    @NamedQuery(name = "Course.findByEctsCredits", query = "SELECT c FROM Course c WHERE c.ectsCredits = :ectsCredits"),
    @NamedQuery(name = "Course.findBySemester", query = "SELECT c FROM Course c WHERE c.semester = :semester"),
    @NamedQuery(name = "Course.findByCourseLanguage", query = "SELECT c FROM Course c WHERE c.courseLanguage = :courseLanguage"),
    @NamedQuery(name = "Course.findByFaculty", query = "SELECT c FROM Course c WHERE c.faculty = :faculty")})
public class Course implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "COURSE_ID")
    private Integer courseId;
    @Basic(optional = false)
    @Column(name = "COURSE_CODE")
    private String courseCode;
    @Basic(optional = false)
    @Column(name = "COURSE_NAME")
    private String courseName;
    @Basic(optional = false)
    @Column(name = "COURSE_NAME_NO")
    private String courseNameNo;
    @Column(name = "ECTS_CREDITS")
    private Short ectsCredits;
    @Column(name = "SEMESTER")
    private Character semester;
    @Column(name = "COURSE_LANGUAGE")
    private Character courseLanguage;
    @Lob
    @Column(name = "PREVIOUS_KNOWLEDGE")
    private String previousKnowledge;
    @Lob
    @Column(name = "PREVIOUS_KNOWLEDGE_NO")
    private String previousKnowledgeNo;
    @Lob
    @Column(name = "COURSE_CONTENT")
    private String courseContent;
    @Lob
    @Column(name = "COURSE_CONTENT_NO")
    private String courseContentNo;
    @Lob
    @Column(name = "STUDY_ACTIVITIES")
    private String studyActivities;
    @Lob
    @Column(name = "STUDY_ACTIVITIES_NO")
    private String studyActivitiesNo;
    @Lob
    @Column(name = "FORM_OF_ASSESSMENT")
    private String formOfAssessment;
    @Lob
    @Column(name = "FORM_OF_ASSESSMENT_NO")
    private String formOfAssessmentNo;
    @Lob
    @Column(name = "RESIT_REQUIREMENTS")
    private String resitRequirements;
    @Lob
    @Column(name = "RESIT_REQUIREMENTS_NO")
    private String resitRequirementsNo;
    @Lob
    @Column(name = "SUPPORT_MATERIAL")
    private String supportMaterial;
    @Lob
    @Column(name = "SUPPORT_MATERIAL_NO")
    private String supportMaterialNo;
    @Lob
    @Column(name = "COURSEWORK_REQUIREMENTS")
    private String courseworkRequirements;
    @Lob
    @Column(name = "COURSEWORK_REQUIREMENTS_NO")
    private String courseworkRequirementsNo;
    @Lob
    @Column(name = "READING_LIST")
    private String readingList;
    @JoinTable(name = "PERSON_COURSE", joinColumns = {
        @JoinColumn(name = "COURSE_ID", referencedColumnName = "COURSE_ID")}, inverseJoinColumns = {
        @JoinColumn(name = "PERSON_ID", referencedColumnName = "PERSON_ID")})
    @ManyToMany
    private Collection<Person> personCollection;
    @JoinTable(name = "STUDY_PROGRAM_COURSE", joinColumns = {
        @JoinColumn(name = "COURSE_ID", referencedColumnName = "COURSE_ID")}, inverseJoinColumns = {
        @JoinColumn(name = "STUDY_PROGRAM_ID", referencedColumnName = "STUDY_PROGRAM_ID")})
    @ManyToMany
    private Collection<StudyProgram> studyProgramCollection;
    @JoinColumn(name = "FACULTY_ID", referencedColumnName = "FACULTY_ID")
    @ManyToOne(optional = false)
    private Faculty faculty;
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "course")
    private Collection<Outcome> outcomeCollection;

    public Course() {
    }

    public Course(Integer courseId) {
        this.courseId = courseId;
    }

    public Course(Integer courseId, String courseCode, String courseName, String courseNameNo) {
        this.courseId = courseId;
        this.courseCode = courseCode;
        this.courseName = courseName;
        this.courseNameNo = courseNameNo;
    }

    public Integer getCourseId() {
        return courseId;
    }

    public void setCourseId(Integer courseId) {
        this.courseId = courseId;
    }

    public String getCourseCode() {
        return courseCode;
    }

    public void setCourseCode(String courseCode) {
        this.courseCode = courseCode;
    }

    public String getCourseName() {
        return courseName;
    }

    public void setCourseName(String courseName) {
        this.courseName = courseName;
    }

    public String getCourseNameNo() {
        return courseNameNo;
    }

    public void setCourseNameNo(String courseNameNo) {
        this.courseNameNo = courseNameNo;
    }

    public Short getEctsCredits() {
        return ectsCredits;
    }

    public void setEctsCredits(Short ectsCredits) {
        this.ectsCredits = ectsCredits;
    }

    public Character getSemester() {
        return semester;
    }

    public void setSemester(Character semester) {
        this.semester = semester;
    }

    public Character getCourseLanguage() {
        return courseLanguage;
    }

    public void setCourseLanguage(Character courseLanguage) {
        this.courseLanguage = courseLanguage;
    }

    public String getPreviousKnowledge() {
        return previousKnowledge;
    }

    public void setPreviousKnowledge(String previousKnowledge) {
        this.previousKnowledge = previousKnowledge;
    }

    public String getPreviousKnowledgeNo() {
        return previousKnowledgeNo;
    }

    public void setPreviousKnowledgeNo(String previousKnowledgeNo) {
        this.previousKnowledgeNo = previousKnowledgeNo;
    }

    public String getCourseContent() {
        return courseContent;
    }

    public void setCourseContent(String courseContent) {
        this.courseContent = courseContent;
    }

    public String getCourseContentNo() {
        return courseContentNo;
    }

    public void setCourseContentNo(String courseContentNo) {
        this.courseContentNo = courseContentNo;
    }

    public String getStudyActivities() {
        return studyActivities;
    }

    public void setStudyActivities(String studyActivities) {
        this.studyActivities = studyActivities;
    }

    public String getStudyActivitiesNo() {
        return studyActivitiesNo;
    }

    public void setStudyActivitiesNo(String studyActivitiesNo) {
        this.studyActivitiesNo = studyActivitiesNo;
    }

    public String getFormOfAssessment() {
        return formOfAssessment;
    }

    public void setFormOfAssessment(String formOfAssessment) {
        this.formOfAssessment = formOfAssessment;
    }

    public String getFormOfAssessmentNo() {
        return formOfAssessmentNo;
    }

    public void setFormOfAssessmentNo(String formOfAssessmentNo) {
        this.formOfAssessmentNo = formOfAssessmentNo;
    }

    public String getResitRequirements() {
        return resitRequirements;
    }

    public void setResitRequirements(String resitRequirements) {
        this.resitRequirements = resitRequirements;
    }

    public String getResitRequirementsNo() {
        return resitRequirementsNo;
    }

    public void setResitRequirementsNo(String resitRequirementsNo) {
        this.resitRequirementsNo = resitRequirementsNo;
    }

    public String getSupportMaterial() {
        return supportMaterial;
    }

    public void setSupportMaterial(String supportMaterial) {
        this.supportMaterial = supportMaterial;
    }

    public String getSupportMaterialNo() {
        return supportMaterialNo;
    }

    public void setSupportMaterialNo(String supportMaterialNo) {
        this.supportMaterialNo = supportMaterialNo;
    }

    public String getCourseworkRequirements() {
        return courseworkRequirements;
    }

    public void setCourseworkRequirements(String courseworkRequirements) {
        this.courseworkRequirements = courseworkRequirements;
    }

    public String getCourseworkRequirementsNo() {
        return courseworkRequirementsNo;
    }

    public void setCourseworkRequirementsNo(String courseworkRequirementsNo) {
        this.courseworkRequirementsNo = courseworkRequirementsNo;
    }

    public String getReadingList() {
        return readingList;
    }

    public void setReadingList(String readingList) {
        this.readingList = readingList;
    }

    public Collection<Person> getPersonCollection() {
        return personCollection;
    }

    public void setPersonCollection(Collection<Person> personCollection) {
        this.personCollection = personCollection;
    }

    public Collection<StudyProgram> getStudyProgramCollection() {
        return studyProgramCollection;
    }

    public void setStudyProgramCollection(Collection<StudyProgram> studyProgramCollection) {
        this.studyProgramCollection = studyProgramCollection;
    }

    public Faculty getFaculty() {
        return faculty;
    }

    public void setFaculty(Faculty faculty) {
        this.faculty = faculty;
    }

    public Collection<Outcome> getOutcomeCollection() {
        return outcomeCollection;
    }

    public void setOutcomeCollection(Collection<Outcome> outcomeCollection) {
        this.outcomeCollection = outcomeCollection;
    }

    @Override
    public int hashCode() {
        int hash = 0;
        hash += (courseId != null ? courseId.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object object) {
        if (!(object instanceof Course)) {
            return false;
        }
        Course other = (Course) object;
        if ((this.courseId == null && other.courseId != null) || (this.courseId != null && !this.courseId.equals(other.courseId))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return courseCode + " " +courseName + " - " + courseNameNo;
    }

    /**
     * Sjekker om søkestreng er en del av resten av strengene i dette objektet.
     * @param searchWord
     * @return true hvis needle er funnet i noen strenger
     */

    public boolean search(String searchWord) {
        String needle = searchWord.toLowerCase();
        if (courseCode != null && courseCode.toLowerCase().contains(needle)) return true;
        if (courseName != null && courseName.toLowerCase().contains(needle)) return true;
        if (courseNameNo != null && courseNameNo.toLowerCase().contains(needle)) return true;
        if (courseContent != null && courseContent.toLowerCase().contains(needle)) return true;
        if (courseContentNo != null && courseContentNo.toLowerCase().contains(needle)) return true;
        /*
        if (studyActivities.contains(searchWord)) return true;
        if (studyActivitiesNo.contains(searchWord)) return true;
        if (resitRequirements.contains(searchWord)) return true;
        if (resitRequirementsNo.contains(searchWord)) return true;
        if (supportMaterial.contains(searchWord)) return true;
        if (supportMaterialNo.contains(searchWord)) return true;
        if (courseworkRequirements.contains(searchWord)) return true;
        if (courseworkRequirementsNo.contains(searchWord)) return true;
        */
        return false;
    }

}
